package aliyun

import (
	"gitee.com/filters/utils/character"
	"github.com/aliyun/aliyun-oss-go-sdk/oss"
	"io"
	"io/ioutil"
	"mime/multipart"
	"strings"
)

// Aliyuner ...
type Aliyuner struct {
	oSSEndPoint     string
	accessKeyId     string
	accessKeySecret string
	bucketName      string
	uploadPath      string
	client          *oss.Client
	bucket          *oss.Bucket
}

type AliOption func(*Aliyuner)

func WithPath(path string) AliOption {
	return func(aliyuner *Aliyuner) {
		aliyuner.uploadPath = path
	}
}

func WithBucket(bucket string) AliOption {
	return func(aliyuner *Aliyuner) {
		aliyuner.bucketName = bucket
	}
}

func WithSecret(secret string) AliOption {
	return func(aliyuner *Aliyuner) {
		aliyuner.accessKeySecret = secret
	}
}

func WithAccessKey(key string) AliOption {
	return func(aliyuner *Aliyuner) {
		aliyuner.accessKeyId = key
	}
}

func WithPoint(point string) AliOption {
	return func(aliyuner *Aliyuner) {
		aliyuner.oSSEndPoint = point
	}
}

func New(opt ...AliOption) *Aliyuner {
	ali := &Aliyuner{
		oSSEndPoint: "http://oss-cn-shenzhen-internal.aliyuncs.com",
	}
	for _, option := range opt {
		option(ali)
	}
	client, err := oss.New(ali.oSSEndPoint, ali.accessKeyId, ali.accessKeySecret)
	if err != nil {
		 panic(err)
	}
	// 指定bucket
	bucket, err := client.Bucket(ali.bucketName) // 根据自己的填写
	if err != nil {
		 panic(err)
	}
	ali.client = client
	ali.bucket = bucket
	return ali
}

func (a *Aliyuner) UploadHttp(file *multipart.FileHeader, fileName string) (string,error) {
	src, err := file.Open()
	if err != nil {
		return "",err
	}
	defer src.Close()
	pathName := a.uploadPath +  getfileId(fileName)
	err = a.bucket.PutObject(pathName, src)
	return getfileId(fileName),err
}

func (a *Aliyuner) UploadFile(  fileName,filePath  string) (string,error) {
	pathName := a.uploadPath + getfileId(fileName)
	return  getfileId(fileName),a.bucket.PutObjectFromFile(pathName, filePath)
}

func (a *Aliyuner) UploadCommon( reader io.Reader, fileName string) (string,error) {
	pathName := a.uploadPath + getfileId(fileName)
	return getfileId(fileName), a.bucket.PutObject(pathName, reader)
}

func (a *Aliyuner) Download(path string) ([]byte, error) {
	var data []byte
	// 下载文件到流。
	body, err := a.bucket.GetObject(path)
	if err != nil {
		return data, err
	}
	// 数据读取完成后，获取的流必须关闭，否则会造成连接泄漏，导致请求无连接可用，程序无法正常工作。
	defer body.Close()
	data, err = ioutil.ReadAll(body)
	if err != nil {
		return data, err
	}
	return data, nil
}

func (a *Aliyuner) CreatePath(path string) error {
	return nil
}

func getfileId(fileName string) string {
	name := fileName
	if strings.Contains(fileName,"/") {
		tempStr := strings.Split(fileName,"/")
		name = tempStr[len(tempStr)-1]
	}
	return character.GetUid() + name
}